MBasic: Hardware, Memory, Variables, Constants
Built-in Hardware The BasicATOM Pro has hardware functions that are independent of the main microcontroller. Examples include: *Analog to digital converters *Pulse width modulators *UARTS *Timers *Capture/Compare modules Built in hardware runs independently of the microcontroller, and can be set up via your program then allowed to run independently. RAM RAM is Random Access Memory, which is "volatile" (i.e. the contents are lost if power is removed). The Atom Pro has 2 kbytes of RAM, the Atom Pro Plus has 4 kbytes. RAM is used to store: *Variables *Values used by the system (registers) - 0 to 256 bytes *Program stack, counters, etc. - approx. 80 to 120 bytes. Remaining RAM is available for user data. Registers The microcontroller on which the Atom Pro is based, uses a number of registers to control its internal operation, set status, etc. These registers occupy memory addresses in RAM. Registers are accessible by using their numeric addresses (see the H8/3664F or H8/3687F hardware manuals for these addresses) or by using the register name. Note:' All H8 register names are pre-defined in Atom BASIC and may be used as variables to access and modify register bits. EEPROM EEPROM is Electrically Erasable Programmable Read Only Memory. It is similar to RAM in that numbers can be stored in EEPROM and retrieved from EEPROM, but it is slower than RAM (particularly for writing values) and has a limited number of write-cycles (about 10 million) before it fails. *The Atom Pro has no built-in EEPROM. An external I2C EEPROM may be connected, see Notes on page 172. *The Atom Pro 28 and Atom Pro Plus 40 have 4 kbytes of EEPROM. EEPROM is normally used for storing constants that don't change frequently. It is accessed by means of the DATA, READ, READDM, WRITE and WRITEDM commands (see page 170). Program Memory (Flash) Programs are stored in "Flash EEPROM" which can be re-written many times. Flash is non-volatile, so your programs will be saved during power off periods. More complex programs require more memory. Program memory can also be used to store constants (see Tables on page 45). The ATOM Pro has 32 kbytes of program memory, the ATOM Pro Plus has 56 kbytes. Flash provides fewer rewrite cycles before failure than EEPROM. Number Types Atom BASIC lets you store numbers with varying precision to minimize memory space requirements. The following number types are used: Use the smallest number type that gives the range and precision you need. This will minimize the use of RAM. Variables Variables are used to store temporary values while your program runs. Like most compiled BASICs, with Atom BASIC you must define your variables before using them. Variables are always stored in user RAM. ' Defining variables ' Variables are defined with the VAR keyword. They may be defined as any of the number types described in Table 1. Remember to define variables as SBYTE, SWORD, SLONG or FLOAT if they may have negative values. '''''Syntax :variable name VAR number type Examples :red var byte :tick var nib :switch var bit :totals var long :fraction var float Note that the compiler will automatically "pack" nib and bit variables to use as few bytes as possible. ' Variable Names ' Variable names must start with a letter, but they can contain letters, numbers, and special characters. They are case-independent so RED and red are the same variable. Variable names may be up to 1024 characters long. We recommend that they be made long enough to be meaningful, but short enough for easy reference. The length of a variable name does not affect the length of your compiled program. You may not define the same variable twice within a program. The following may not be used for variable names: *Atom BASIC reserved words (see page 191) *label names used within your program Important:' Please note that the following single letters are reserved and may not be used as variables: b, c, d, p, r, s, z. ''Note: Some of the examples in this manual use selected single letter variables for brevity and simplicity in short code segments.'' Array variables (strings) Arrays are special variables used in BASIC to hold a number of related values. Atom BASIC provides for linear arrays (also known as one-dimensional arrays or "subscripted" variables). ''Important: Array variables should not use the same names as existing simple variables. See page 184 for more information about this.'' '''''Syntax to Define an Array :variable name VAR number type(number of cells) Example Suppose you want to store values for 5 temperature sensors in an array. Each sensor requires a WORD value. Define the array as: :temp var word(5) This sets aside 5 "words" in RAM for your array, numbered 0 to 4. Note:' Atom BASIC numbers arrays starting from 0, so the first value is arrayname(0) etc. The last value is arrayname(4) in this case. (If you find counting from 0 confusing, simply define your array to have one more cell than needed, and ignore cell 0. This wastes one cell, of course.) You can access each value as if it was a separate variable, for example you can access the third value as: :word(2) The number "2" in this case is called the "index". The third value has an index of 2 because the array is numbered 0, 1, 2, 3, 4. When accessing array values, the index can be a variable: :cntr var byte :temp var word(5) :for cntr=0 to 4 ::temp(cntr)= cntr+15 :next This will assign the values of 15, 16, 17, 18 and 19 to the array cells, so that temp(3) would have a value of 18, etc. Using Array Variables to Hold Strings A common use of array variables is to hold "strings" of ASCII characters. When used for this purpose, arrays should be defined as byte variables. ''Important: Bounds checking is not performed. It is the programmer's responsibility to make sure that the string to be stored does not exceed the length of the array. (If the string length exceeds the array length, characters will simply overwrite the next variable(s) in the order that they were originally defined.)'' '''''Example The following program excerpt will illustrate this use of array variables. :var byte mystring(20) :mystring = "This is a test" This will assign "T" to mystring(0), "h" to mystring(1), etc. Aliases An alias gives you a means of assigning more than one name to the same variable. You may need temporary variables at different points in your program, but not want to use too much RAM to store all of them. Syntax :new variable VAR existing variable Example :sensor VAR byte :eye VAR sensor This will create a variable "eye" that points to the same RAM location as the variable "sensor". In your program you might have a loop: :for sensor = 1 to 10 ::(some code or other) :next Then later in your program you could have a loop: :for eye = 2 to 8 ::(some code or other) :next Sensor and eye would use the same RAM location, thus saving 1 byte of RAM. Variable Modifiers Variable modifiers are used to access parts of a variable. For example, you could access the high or low nibble of a "byte" variable. Modifiers can be used both when variables are defined, and "on the fly" during program execution. Note:' Modifiers won't work with FLOAT type variables. '''''Syntax :variable.modifier A complete list of modifiers appears on page 41. Example 1 Example 1 shows an alias that accesses only part of a variable. The modifier is used to define a variable. :sensor VAR byte :eye VAR sensor.highnib Sensor is a byte (8 bit) variable. Eye is defined as the high nibble (most significant 4 bits) of Sensor. Changing the value of Eye will change only the top 4 bits of Sensor. Example 2 Example 2 shows the use of modifiers during execution of a program. First, the variables are defined: :maxval VAR word :topval VAR byte Then, at a later point in the program, the statement: :topval = maxval.highbyte Assigns the value contained in the high 8 bits of maxval to topval. (We could also have used maxval.byte1 to get the same value in this example.) Note:' When using variable modifiers, be sure to keep track of the length of each variable as defined by its number type. '''''Example 3 Variable modifiers can be used in conditional statements: :if maxval.bit0 = 0 then even Where "even" is a label. Note that if bit0 = 0 the number must be an even number, so this test can be used to determine if a number is even or odd. List of Modifiers The following modifiers are allowed. Note that in some cases different modifiers will give the same result (for example, in a "word" variable, "highbyte" and "byte1" are the same). Pin Variables (Ports) Pin variables are special bit-mapped variables used to set the direction and set or read the state of any I/O pin. Pin Variables are also known as Ports. Note:' The tables below show pins 0 to 31. Please refer to the data sheet for your module to determine which pins are actually available. '''''Direction At program start all I/O pins are set as inputs. Directions can be set using the Input and Output commands, or using a Pin variable from the following list: Each direction bit must be set to 0 for input and 1 for output. State The state of an I/O pin can be read or set using the IN and OUT pin variables. Note:' IN and OUT are interchangeable; the two names are provided for compatibility with other BASIC implementations and for clarity in programming. Whether a state is set or read is determined by the direction assigned to the pin. The table below shows all IN and OUT Pin variables: The state bit is 0 for low and 1 for high. '''''Examples As an example, let's say we want to set P0 to P3 as inputs and P4 to P7 as outputs. Here are two different ways to accomplish the same thing. Using 4 bit variables: :... :dira = 15 ; 15 decimal = 1111 binary :dirb = 0 ; 0 decimal = 0000 binary :... Using an 8 bit variable: :... :dirl = 15 ; 15 decimal = 00001111 binary :... Now we want to set and read the I/O pins we've set up. Let's say we expect the following, where 0 = low and 1 = high: Using two 4 bit variables: :... :outa = 11 ; 11 decimal = 1011 binary :status = inb ; status will equal 6 decimal :; or 0110 binary :... Note:' We've used "out" for output and "in" for input to make it easier to understand the program snippet. In fact, any combination of "out" and "in" would work equally well (but could be confusing to read). Constants Constants are similar to variables except that the values are set at compile time and can't be changed by the program while it's running. Think of a constant as a convenient way to give a name to a numeric value so you don't have to remember what it is each time it's used. ''Note: Constants are stored in program memory (see page 36), not in RAM. This frees valuable RAM for variables as well as making constants non-volatile. The values of constants are stored when the program is downloaded from the IDE to the Atom Pro.'' Defining Constants Constants are defined with the CON keyword. The numeric type is automatically set by the compiler based on the value you enter. '''''Syntax :constant name CON value of constant Examples :temperature_adjust CON 24 :kilo CON 1000 :true CON 1 :false CON 0 :endpoint CON -3442567 Constant Names Names of constants follow the same rules as names of variables, see page 45. Tables Tables are to constants as Arrays are to variables. A table can be used to store a number of related constants which are then referred to using the index number. Note:' Tables are stored in program memory (see page 36), not in user RAM. This frees valuable RAM for variables and makes Tables non-volatile. The table contents are written to program memory while the Atom Pro is being programmed, therefore defined constants and variables can NOT be used to populate tables. However, the table is accessed from within a running program, so variables can be used to "index" into a table. '''''Syntax :tablename TableType data, data, data... Table names follow the same rules as variable and constant names. TableType can be any of the following: *ByteTable (8 bit data) *WordTable (16 bit data) *LongTable (32 bit data) *FloatTable (floating point data) Byte Tables can also be used to store "string" values. data is a constant, or a series of constants or constant expressions. Variables and named constants can't be used as data because the table is populated before your program starts running. However, expressions such as 3 * 10 are legal. Examples :adjust WordTable 100,350,5678,73,9,8133*3,0 This creates a constant array with values as shown. Cell numbering starts with 0, so the value of "adjust(3)" would be 73. As with arrays, when referring to the table the index can be a variable. :letter ByteTable "This is a test",0 This creates a constant array containing a string value, terminated with a zero. In this example the value of "letter(0)" would be "T", the value of "letter(3)" would be "s", etc. Terminating the table with 0 allows you to test for the end of the table, without knowing how many characters it contains. Note:' One should not make assumptions that if 2 bytetables follow each other that the bytes will be consecutive. IE :X1 bytetable “Cat” :X2 bytetable “Dog” May not necessarily generate the exact same byte steam as :X bytetable “cat”,”dog” As the compiler may insert a trailing 0 byte to align the memory. Pin Constants ''Note: This section shows pins P0 to P31. Please refer to the data sheet for your module to determine which pins are actually available.'' Pin constants are pre-defined for easy reference to I/O pins. :P0 = 0 :P1 = 1 :... :P31 = 31 '''''Example I/O pin 8 could be set to Output state and to High (5V) using either: :high 8 or :high P8 Another example of the use of Pin constants can be found in the Traffic Light program on page 23. Each Atom Pro module also has two special serial I/O pins used for programming and serial data communications. They can be referred to in your program as: S_IN and S_OUT See the appropriate data sheet to identify these pins.